package com.zhongwang.mms.util;


import com.zhongwang.mms.constant.Constant;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @Description: 对象比较工具类
 *
 * @author: China.sgl
 * @Date: 2019/8/7 15:47
 */
public class BeanUtil {

    /**
     * 比罗属性，返回值不同的字符串
     *
     * @param before
     * @param after
     * @param ignoreProperties
     * @return
     */
    public static String compare(Object before, Object after, String... ignoreProperties) {
        StringBuilder sb = new StringBuilder();
        final BeanWrapper beforeWrapper = new BeanWrapperImpl(before);
        PropertyDescriptor[] beforePds = beforeWrapper.getPropertyDescriptors();
        List<String> ignoreList = ignoreProperties != null ? Arrays.asList(ignoreProperties) : null;
        for (PropertyDescriptor beforePd : beforePds) {
            if (ignoreList == null || !ignoreList.contains(beforePd.getName())) {
                try {
                    PropertyDescriptor afterPd = new PropertyDescriptor(beforePd.getName(), after.getClass());
                    Method beforeMethod = beforePd.getReadMethod();
                    Method afterMethod = afterPd.getReadMethod();
                    Object beforeValue = beforeMethod.invoke(before);
                    Object afterValue = afterMethod.invoke(after);
                    if (beforeValue != null && afterValue != null
                            && !beforeValue.toString().equals(afterValue.toString())
                            && Constant.FIELD_NAME.get(beforePd.getName()) != null) {
                        sb.append(Constant.FIELD_NAME.get(beforePd.getName()))
                                .append("：【")
                                .append(beforeValue)
                                .append("】 -> 【")
                                .append(afterValue)
                                .append("】<br>");
                    }
                } catch (Exception e) {
                    continue;
                }
            }


        }
        if (sb.toString().length() == 0) {
            sb.append("-");
        }
        return sb.toString();
    }

    public static String compare(Object before, Object after) {
        return compare(before, after, null);
        /*StringBuilder sb = new StringBuilder();
        try {
            Class clazz = before.getClass();
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
                Method getMethod = pd.getReadMethod();
                Object obj1 = getMethod.invoke(before);
                Object obj2 = getMethod.invoke(after);
                String s1 = obj1 == null ? "" : obj1.toString();
                String s2 = obj2 == null ? "" : obj2.toString();
                if (obj1 != null && obj2 != null && !s1.equals(s2) && Constant.FIELD_NAME.get(field.getName()) != null) {
                    sb.append(Constant.FIELD_NAME.get(field.getName()))
                            .append("：【")
                            .append(s1)
                            .append("】 -> 【")
                            .append(s2)
                            .append("】<br>");
                }
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        if (sb.toString().length() == 0) {
            sb.append("-");
        }
        return sb.toString();*/
    }


    /**
     * 获取需要忽略的属性
     *
     * @param source
     * @return
     */
    public static String[] getNullPropertyNames (Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<>();
        for(PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) {
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    /**
     * 复制对象，并排除空属性
     *
     * @param source
     * @param target
     */
    public static void copy(Object source, Object target) {
        BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
    }

}
